export default {
  // checkData(data: any, type: string | CheckType): boolean
  checkData(data, type) {
    return this.verifyData(data, type).success;
  },

  // verifyData(data: any, type: string | CheckType): IVerifyData
  verifyData(data, type) {
    if (data == undefined || data == null) {
      return {
        success: false,
        data: null
      };
    }
    let value = typeof data == "string" ? data.trim() : data + "";
    if (type) {
      let callback = checkMap.get(type);
      if (callback) {
        return {
          success: callback(value),
          data: value
        };
      }
    }
    return {
      success: true,
      data: value
    };
  },

  // formatData(data: any, type: string | FormatType, option ? : string): any
  formatData(data, type, option) {
    if (type) {
      let callback = formatMap.get(type);
      if (callback) {
        return callback(data, option);
      }
    }
    return data;
  },

  // getUrlSuffixObj(url: string | undefined | null): object | null
  getUrlSuffixObj(url) {
    if (!url) {
      return null;
    }
    let realUrl = decodeURIComponent(url);
    if (!realUrl) {
      return null;
    }
    if (realUrl.endsWith("#/")) {
      realUrl = realUrl.substring(0, realUrl.length - 2);
    }
    let index = realUrl.indexOf("?");
    if (index < 0 || (index + 1) >= realUrl.length) {
      return null;
    }
    let str = realUrl.substring(index + 1, realUrl.length);
    let obj = null;
    let array = str.split("&");
    for (let i = 0; i < array.length; i++) {
      let item = array[i];
      let itemIndex = item.indexOf("=");
      if (itemIndex >= 0 && itemIndex < item.length) {
        let itemKey = item.substring(0, itemIndex);
        let itemValue = item.substring(itemIndex + 1, item.length);
        if (!obj) {
          obj = {};
        }
        obj[itemKey] = itemValue;
      }
    }
    return obj;
  },

  // getHtmlStyleObj(style: string | undefined | null): object | null
  getHtmlStyleObj(style) {
    if (!style) {
      return null;
    }
    let obj = null;
    style.trim().split(";").forEach(item => {
      let subArray = item.split(":");
      if (subArray.length == 2) {
        let key = subArray[0].trim();
        let realkey = "";
        let forceUp = false;
        for (let i = 0; i < key.length; i++) {
          let keyItem = key.charAt(i);
          if (keyItem == "-") {
            forceUp = true;
          } else {
            if (forceUp) {
              forceUp = false;
              realkey += keyItem.toUpperCase();
            } else {
              realkey += keyItem;
            }
          }
        }
        if (realkey.length > 0) {
          if (!obj) {
            obj = {};
          }
          obj[realkey] = subArray[1].trim();
          try {
            let result = JSON.parse(obj[realkey]);
            if (typeof result == "object") {
              obj[realkey] = result;
            }
          } catch (e) {}
        }
      }
    });
    return obj;
  },

  // getArrayByFormat(array: any[], keyCallback ? : typeof FormatKeyCallback, valueCallback ? : typeof FormatValueCallback): any[]
  getArrayByFormat(array, keyCallback, valueCallback) {
    if (array && array.length > 0 && (keyCallback || valueCallback)) {
      return array.map(function (item) {
        if (!item) {
          return item;
        }
        let destItem = {};
        for (let key in item) {
          let value = item[key];
          if (keyCallback) {
            key = keyCallback(key, value);
          }
          if (valueCallback) {
            value = valueCallback(value, key);
          }
          destItem[key] = value;
        }
        return destItem;
      });
    }
    return array;
  },

  // getArrayByNoRepeat(array: any[]): any[]
  getArrayByNoRepeat(array) {
    if (array && array.length > 0) {
      let map = new Map();
      for (let i = 0; i < array.length; i++) {
        if (array[i]) {
          map.set(array[i], i);
        }
      }
      if (map.size > 0) {
        let realArray = [];
        map.forEach(function (value, key) {
          realArray.push(key);
        });
        return realArray;
      }
    }
    return array;
  },
}

var checkMap = new Map();
checkMap.set("integer", function (value) { // 是否是正整数
  return /^[0-9]*$/.test(value);
});
checkMap.set("number", function (value) { // 是否是正数
  if (value.length < 1) {
    return false;
  }
  let result = Number(value);
  if (isNaN(result)) {
    return false;
  }
  return result >= 0;
});
checkMap.set("integerAll", function (value) { // 是否是整数
  return /^[0-9]*$/.test(value) || /^-[0-9]*$/.test(value);
});
checkMap.set("numberAll", function (value) { // 是否是数字
  if (value.length < 1) {
    return false;
  }
  return !isNaN(Number(value));
});
checkMap.set("phone", function (value) { // 是否是手机号码
  return /^1(3|4|5|6|7|8|9)\d{9}$/.test(value);
});
checkMap.set("carNumber", function (value) { // 是否是车牌号码
  return /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]{1}$/.test(value) ||
    /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-Z0-9]{6}$/.test(value);
});
checkMap.set("idCard", function (value) { // 是否是身份证号码
  return /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/.test(value);
});
checkMap.set("email", function (value) { // 是否是email
  return /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/.test(value);
});
checkMap.set("http", function (value) { // 是否以http开头
  return value.toLocaleLowerCase().startsWith("http://") || value.toLocaleLowerCase().startsWith("https://");
});
checkMap.set("https", function (value) { // 是否以https开头
  return value.toLocaleLowerCase().startsWith("https://");
});

var formatMap = new Map();
formatMap.set("time", getFormatTime);
formatMap.set("timeLen", getFormatTimeByLen);
formatMap.set("timeNumber", getTimeNumber);
formatMap.set("date", getDateByType);
formatMap.set("price", toPrice);
formatMap.set("floorPrice", toFloorPrice);
formatMap.set("chinesePrice", toChinesePrice);

// "yyyy年MM月dd日HH小时mm分钟ss秒"
// getFormatTime(data: any, format: string): string
function getFormatTime(data, format) {
  if (!format) {
    return "";
  }
  if (data == undefined || data == null) {
    return "";
  }
  let date = getDate(data);
  if (!date) {
    return "";
  }
  let result = format;
  if (result.indexOf("yyyy") > -1) {
    result = result.replace("yyyy", date.getFullYear() + "");
  }
  if (result.indexOf("MM") > -1) {
    let temp = date.getMonth() + 1;
    result = result.replace("MM", temp < 10 ? "0" + temp : "" + temp);
  }
  if (result.indexOf("dd") > -1) {
    let temp = date.getDate();
    result = result.replace("dd", temp < 10 ? "0" + temp : "" + temp);
  }
  if (result.indexOf("HH") > -1) {
    let temp = date.getHours();
    result = result.replace("HH", temp < 10 ? "0" + temp : "" + temp);
  }
  if (result.indexOf("mm") > -1) {
    let temp = date.getMinutes();
    result = result.replace("mm", temp < 10 ? "0" + temp : "" + temp);
  }
  if (result.indexOf("ss") > -1) {
    let temp = date.getSeconds();
    result = result.replace("ss", temp < 10 ? "0" + temp : "" + temp);
  }
  return result;
}

// "dd天HH小时mm分钟ss秒"
// getFormatTimeByLen(data: any, format: string): string
function getFormatTimeByLen(data, format) {
  if (!format) {
    return "";
  }
  if (data == undefined || data == null) {
    return "";
  }
  let left = data;
  if (typeof left != "number") {
    left = Number(left);
    if (isNaN(left)) {
      return "";
    }
  }
  if (left < 0) {
    left = -left;
  }
  let result = format;
  if (result.indexOf("dd") > -1) {
    let temp = Math.floor(left / 86400);
    result = result.replace("dd", temp < 10 ? "0" + temp : "" + temp);
    left = left % 86400;
  }
  if (result.indexOf("HH") > -1) {
    let temp = Math.floor(left / 3600);
    result = result.replace("HH", temp < 10 ? "0" + temp : "" + temp);
    left = left % 3600;
  }
  if (result.indexOf("mm") > -1) {
    let temp = Math.floor(left / 60);
    result = result.replace("mm", temp < 10 ? "0" + temp : "" + temp);
    left = left % 60;
  }
  if (result.indexOf("ss") > -1) {
    result = result.replace("mm", left < 10 ? "0" + left : left);
  }
  return result;
}

// getTimeNumber(data: any): number
function getTimeNumber(data) {
  if (data == undefined || data == null) {
    return 0;
  }
  if (data instanceof Date) {
    let value = data.getTime();
    if (isNaN(value)) {
      return 0;
    }
    return value / 1000;
  }
  if (typeof data == "number") {
    return data;
  }
  if (typeof data == "string") {
    try {
      let value = Date.parse(setTimeString(data));
      if (isNaN(value)) {
        return 0;
      }
      return value / 1000;
    } catch (e) {}
  }
  return 0;
}

// "none"或"start"（00时00分00秒）或"end"（23时59分59秒），不传则为"none"
// getDateByType(data: any, type ? : string): Date | null
function getDateByType(data, type) {
  let result = getDate(data);
  if (!result) {
    return result;
  }
  if (type == "start") {
    result = getDate(result.toLocaleDateString());
  } else if (type == "end") {
    result = getDate(result.toLocaleDateString());
    if (result) {
      result = getDate(result.getTime() + 24 * 60 * 60 * 1000 - 1);
    }
  }
  return result;
}

// getDate(data: any): Date | null
function getDate(data) {
  if (data == undefined || data == null) {
    return new Date();
  }
  if (data instanceof Date) {
    if (!isNaN(data.getTime())) {
      return data;
    }
    return null;
  }
  if (typeof data == "number") {
    return new Date(data * 1000);
  }
  if (typeof data == "string") {
    let nData = Number(data);
    if (!isNaN(nData)) {
      return new Date(nData * 1000);
    }
    let date;
    try {
      date = new Date(data);
      if (!isNaN(date.getTime())) {
        return date;
      }
      date = null;
    } catch (e) {
      date = null;
    }
    let value = setTimeString(data);
    try {
      let array = value.split(" ");
      for (let i = 0; i < array.length; i++) {
        let item = array[i];
        if (item.indexOf("/") > -1) {
          date = setDateByDay(item, date);
        } else if (item.indexOf(":") > -1) {
          date = setDateByHour(item, date);
        }
      }
      return date;
    } catch (e) {}
  }
  return null;
}

// setTimeString(str: string): string
function setTimeString(str) {
  return str.replace(/-/g, "/").replace(/年/g, "/").replace(/月/g, "/").replace(/日/g, " ")
    .replace(/：/g, ":").replace(/小时/g, ":").replace(/分钟/g, ":").replace(/秒/g, " ")
    .replace(/点/g, ":").replace(/分/g, ":");
}

// setDateByDay(param: string, date: Date | null): Date | null
function setDateByDay(param, date) {
  let array = param.split("/");
  if (array.length == 3) { // 判断成年、月、日
    if (checkNumberArray(array)) {
      let year, day;
      if (array[2] > array[0]) {
        year = array[2];
        day = array[0];
      } else {
        year = array[0];
        day = array[2];
      }
      if (array[1] >= 1 && array[1] <= 12 && day >= 1 && day <= 31) {
        if (!date) {
          date = new Date();
        }
        date.setUTCFullYear(year, array[1] - 1, day);
      }
    }
  } else if (array.length == 2) { // 判断成月和日
    if (checkNumberArray(array)) {
      if (array[0] >= 1 && array[0] <= 12 && array[1] >= 1 && array[1] <= 31) {
        if (!date) {
          date = new Date();
        }
        date.setUTCFullYear(date.getFullYear(), array[0] - 1, array[1]);
      }
    }
  }
  return date;
}

// setDateByHour(param: string, date: Date | null): Date | null
function setDateByHour(param, date) {
  let array = param.split(":");
  if (array.length == 3) { // 判断成小时、分钟、秒
    if (checkNumberArray(array)) {
      if (array[0] >= 0 && array[0] <= 24 && array[1] >= 0 && array[1] <= 59 &&
        array[2] >= 0 && array[2] <= 59) {
        if (!date) {
          date = new Date();
        }
        date.setUTCHours(array[0] - 8, array[1], array[2]);
      }
    }
  } else if (array.length == 2) { // 判断成小时、分钟
    if (checkNumberArray(array)) {
      if (array[0] >= 0 && array[0] <= 24 && array[1] >= 0 && array[1] <= 59) {
        if (!date) {
          date = new Date();
        }
        date.setUTCHours(array[0] - 8, array[1], 0);
      }
    }
  }
  return date;
}

// checkNumberArray(array: any[]): boolean
function checkNumberArray(array) {
  for (let i = 0; i < array.length; i++) {
    let item = Number(array[i]);
    if (isNaN(item)) {
      return false;
    }
    array[i] = item;
  }
  return true;
}

// 精确到小数点的位数，不传则为2
// toPrice(data: any, ratio ? : any): number
function toPrice(data, ratio) {
  if (data == undefined || data == null) {
    return 0;
  }
  let result = data;
  if (typeof result != "number") {
    result = Number(result);
    if (isNaN(result)) {
      return 0;
    }
  }
  let realRatio = ratio;
  if (realRatio == undefined || realRatio == null) {
    realRatio = 2;
  } else if (typeof realRatio != "number") {
    realRatio = Number(realRatio);
    if (isNaN(realRatio)) {
      realRatio = 2;
    }
  }
  realRatio = Math.pow(10, realRatio);
  return Math.round((result + 0.0000000003) * realRatio) / realRatio;
}

// 精确到小数点的位数，不传则为2
// toFloorPrice(data: any, ratio ? : any): number
function toFloorPrice(data, ratio) {
  if (data == undefined || data == null) {
    return 0;
  }
  let result = data;
  if (typeof result != "number") {
    result = Number(result);
    if (isNaN(result)) {
      return 0;
    }
  }
  let realRatio = ratio;
  if (realRatio == undefined || realRatio == null) {
    realRatio = 2;
  } else if (typeof realRatio != "number") {
    realRatio = Number(realRatio);
    if (isNaN(realRatio)) {
      realRatio = 2;
    }
  }
  realRatio = Math.pow(10, realRatio);
  return Math.floor((result + 0.0000000003) * realRatio) / realRatio;
}

// "simple"或"tradition"，不传则为"simple"
// toChinesePrice(data: any, type ? : string): string
function toChinesePrice(data, type) {
  // TODO
  if (data == undefined || data == null) {
    return "";
  }
  let str = data;
  if (typeof str != "number") {
    str = Number(str);
    if (isNaN(str)) {
      return "";
    }
  }
  str += "";
  let result = "";
  let hasZero = false;
  for (let i = 0; i < str.length; i++) {
    let item = str.charAt(i);
    if (item == "0") {
      hasZero = true;
      continue;
    }
    let itemValue = getChineseMap(type).get(item);
    if (itemValue == undefined) {
      continue;
    }
    let itemBit = getChineseBitArray()[str.length - 1 - i];
    if (itemBit == undefined) {
      continue;
    }
    if (hasZero) {
      hasZero = false;
      result += "零";
    }
    result += itemValue + itemBit;
  }
  return result;
}

var chineseMap = null; // Map <string, string> | null
var chineseSimpleMap = null; // Map <string, string> | null
var chineseBitArray = null; // string[] | null

// getChineseMap(type ? : string): Map <string, string>
function getChineseMap(type) {
  if (type == "tradition") {
    if (chineseMap) {
      return chineseMap;
    }
    chineseMap = new Map();
    chineseMap.set("0", "零");
    chineseMap.set("1", "壹");
    chineseMap.set("2", "贰");
    chineseMap.set("3", "叁");
    chineseMap.set("4", "肆");
    chineseMap.set("5", "伍");
    chineseMap.set("6", "陆");
    chineseMap.set("7", "柒");
    chineseMap.set("8", "捌");
    chineseMap.set("9", "玖");
    return chineseMap;
  } else {
    if (chineseSimpleMap) {
      return chineseSimpleMap;
    }
    chineseSimpleMap = new Map();
    chineseSimpleMap.set("0", "一");
    chineseSimpleMap.set("1", "二");
    chineseSimpleMap.set("2", "三");
    chineseSimpleMap.set("3", "四");
    chineseSimpleMap.set("4", "五");
    chineseSimpleMap.set("5", "六");
    chineseSimpleMap.set("6", "七");
    chineseSimpleMap.set("7", "八");
    chineseSimpleMap.set("8", "九");
    chineseSimpleMap.set("9", "十");
    return chineseSimpleMap;
  }
}

// getChineseBitArray(): string[]
function getChineseBitArray() {
  if (chineseBitArray) {
    return chineseBitArray;
  }
  chineseBitArray = ["", "十", "百", "千", "万", "十万", "百万", "千万", "亿", "十亿", "百亿", "千亿", "万亿"];
  return chineseBitArray;
}